package cn.dkk.Extend.Util;

import cn.dkk.Extend.anno.StringConvert;

import java.lang.reflect.Field;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.math.BigDecimal;
import java.util.List;

/**
 * @author dkk
 * @date 2022/7/14
 * @desc 通过反射copy两个对象同属性名不同类型的属性
 * @version 2.0
 */
public class ConvertUtils2 {

    public static void copyProperties(Object source, Object target) throws IllegalAccessException, InstantiationException {
        Field[] sourceFields = source.getClass().getDeclaredFields();
        Field[] targetFields = target.getClass().getDeclaredFields();
        for (Field sourceField : sourceFields) {
            for (Field targetField : targetFields) {
                if (sourceField.getName().equals(targetField.getName())) {
                    boolean isStoreType = sourceField.isAnnotationPresent(StringConvert.class);
                    targetField.setAccessible(true);
                    sourceField.setAccessible(true);
                    if (isStoreType) {
                        Object tarf = targetField.get(target);
                        // 如果成员变量为null,则实例化一个成员变量赋值
                        if (tarf == null) {
                            tarf = targetField.getType().newInstance();
                        }
                        Object souf = sourceField.get(source);
                        copyProperties(souf, tarf);
                    } else {
                        convert(source, target, sourceField, targetField);
                    }
                }
            }
        }
    }

    private static void convert(Object source, Object target, Field sourceField, Field targetField) throws IllegalAccessException, InstantiationException {
        Class<?> type = targetField.getType();
        if (type == String.class) {
            targetField.set(target, sourceField.get(source));
        } else if (type == BigDecimal.class) {
            targetField.set(target, new BigDecimal((String) sourceField.get(source)));
        }
    }

    public static<T,E> void listHandle(List<T> sourceList, List<E> targetList ,Class<E> clazz) throws IllegalAccessException, InstantiationException {
        for (int i = 0; i < sourceList.size(); i++) {
            T t = sourceList.get(i);
            E e;
            if (targetList.size()<=i) {
                  e=clazz.newInstance();
            }else{
                e=targetList.get(i);
            }
            copyProperties(t,e);
            targetList.add(e);
        }
    }

    private static Class<?> getT(Field field) {
        Type genericType = field.getGenericType();
        // 如果是泛型参数的类型
        if(genericType instanceof ParameterizedType){
            ParameterizedType pt = (ParameterizedType) genericType;
            //得到泛型里的class类型对象
            return (Class<?>)pt.getActualTypeArguments()[0];
        }
        return null;
    }
}
